"""
Test pygmt.grdsample.
"""

from pathlib import Path

import pytest
import xarray as xr
from pygmt import grdsample
from pygmt.enums import GridRegistration, GridType
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import GMTTempFile
from pygmt.helpers.testing import load_static_earth_relief


@pytest.fixture(scope="module", name="grid")
def fixture_grid():
    """
    Load the grid data from the static_earth_relief file.
    """
    return load_static_earth_relief()


@pytest.fixture(scope="module", name="region")
def fixture_region():
    """
    Return the region settings for the grdsample tests.
    """
    return [-53, -47, -20, -15]


@pytest.fixture(scope="module", name="spacing")
def fixture_spacing():
    """
    Return the spacing settings for the grdsample tests.
    """
    return [2, 1]


@pytest.fixture(scope="module", name="expected_grid")
def fixture_expected_grid():
    """
    Load the expected grdsample grid result.
    """
    return xr.DataArray(
        data=[
            [460.84375, 482.78125, 891.09375],
            [680.46875, 519.09375, 764.9375],
            [867.75, 579.03125, 852.53125],
            [551.75, 666.6875, 958.21875],
            [411.3125, 518.4375, 931.28125],
        ],
        coords={
            "lon": [-52, -50, -48],
            "lat": [-19.5, -18.5, -17.5, -16.5, -15.5],
        },
        dims=["lat", "lon"],
    )


def test_grdsample_file_out(grid, expected_grid, region, spacing):
    """
    Test grdsample with an outgrid set and the spacing is changed.
    """
    with GMTTempFile(suffix=".nc") as tmpfile:
        result = grdsample(
            grid=grid, outgrid=tmpfile.name, spacing=spacing, region=region
        )
        assert result is None  # return value is None
        assert Path(tmpfile.name).stat().st_size > 0  # check that outgrid exists
        temp_grid = xr.load_dataarray(tmpfile.name, engine="gmt", raster_kind="grid")
        xr.testing.assert_allclose(a=temp_grid, b=expected_grid)


@pytest.mark.benchmark
def test_grdsample_dataarray_out(grid, expected_grid, region, spacing):
    """
    Test grdsample with no outgrid set and the spacing is changed.
    """
    result = grdsample(grid=grid, spacing=spacing, region=region, cores=2)
    # check information of the output grid
    assert isinstance(result, xr.DataArray)
    assert result.gmt.gtype is GridType.GEOGRAPHIC
    assert result.gmt.registration is GridRegistration.PIXEL
    # check information of the output grid
    xr.testing.assert_allclose(a=result, b=expected_grid)


def test_grdsample_registration_changes(grid):
    """
    Test grdsample with no set outgrid and applying registration changes.
    """
    assert grid.gmt.registration is GridRegistration.PIXEL
    translated_grid = grdsample(grid=grid, toggle=True)
    assert translated_grid.gmt.registration is GridRegistration.GRIDLINE
    registration_grid = grdsample(grid=translated_grid, registration="pixel")
    assert registration_grid.gmt.registration is GridRegistration.PIXEL


def test_grdsample_toggle_and_registration_mutually_exclusive(grid):
    """
    Raise an exception if toggle and registration are both set.
    """
    with pytest.raises(GMTInvalidInput):
        grdsample(grid=grid, toggle=True, registration="pixel")
